AWS SAM+TypeScriptでLINE Bot のサンプルを作成してみました(小ネタ)
1 はじめに
AIソリューション部の平内(SIN)です。
サーバ側にAWS LambdaとAPI Gatewayを使用した、LINE Botの作り方(入門バージョン)が、下記の記事で公開されています。
今回は、こちらをAWS SAMとTypeScriptでやってみました。
すいません、特にヒネリがあるわけではありません。LINEデベロッパーコンソールでの、チャンネル設定などは、全て上記の記事をご参照下さい。
2 TypeScript
TypeScriptは、/srcの下で.tsを編集し、/dstの下に出力するようにしました。
tsconfig.json
{ "compilerOptions": { "target": "es6", "module": "commonjs", "sourceMap": true, "alwaysStrict": true,// use strict; "noUnusedLocals": true, // 未使用変数 "noUnusedParameters": true,// 未使用引数 "noImplicitAny": true, // 暗黙のAny "allowUnreachableCode": false,// 到達しないコード "allowUnusedLabels": false,// 到達しないラベル "strictNullChecks": true,// null チェック "noImplicitReturns": true,// 戻り値 "outDir": "./dst", // 出力ディレクトリ "rootDir": "./src" // ソースディレクトリ } }
そして、ボットのコードが下記のとおりです。
index.ts
import * as Lambda from 'aws-lambda'; import * as Line from "@line/bot-sdk"; import * as Types from "@line/bot-sdk/lib/types"; const accessToken = process.env.ACCESS_TOKEN!; const channelSecret = process.env.CHANNEL_SECRET!; const config: Line.ClientConfig = { channelAccessToken: accessToken, channelSecret: channelSecret, }; const client = new Line.Client(config); async function eventHandler(event:Line.WebhookEvent): Promise<any> { if (event.type !== 'message' || event.message.type !== 'text') { return null; } const message: Types.Message = { type: "text", text: event.message.text + "ってか?" }; return client.replyMessage(event.replyToken, message); } export const handler: Lambda.APIGatewayProxyHandler = async (proxyEevent:Lambda.APIGatewayEvent, _context) => { console.log(JSON.stringify(proxyEevent)); // 署名確認 const signature = proxyEevent.headers["X-Line-Signature"]; if (!Line.validateSignature(proxyEevent.body!, channelSecret, signature)) { throw new Line.SignatureValidationFailed("signature validation failed", signature); } const body: Line.WebhookRequestBody = JSON.parse(proxyEevent.body!); await Promise .all(body.events.map( async event => eventHandler(event))) .catch( err => { console.error(err.Message); return { statusCode: 500, body: "Error" } }) return { statusCode: 200, body: "OK" } }
3 AWS SAM
使用したテンプレートは、以下のとおりです。ACCESS_TOKENとCHANNEL_SECRETをLINE側のチャンネル設定からコピーするだけで、使い回せると思います。
template.yml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: line-bot-sample Globals: Function: Timeout: 3 Environment: Variables: ACCESS_TOKEN: xxxxxx CHANNEL_SECRET: xxxxxxx Resources: LINEBotSampleFunction: Type: AWS::Serverless::Function Properties: CodeUri: dst/ Handler: index.handler Runtime: nodejs10.x Events: LINEBotSample: Type: Api Properties: Path: / Method: post Outputs: LINEBotSampleApi: Description: "API Gateway endpoint URL for Prod stage for LINE Bot Sample function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/" LINEBotSampleFunction: Description: "LINE Bot Sample Lambda Function ARN" Value: !GetAtt LINEBotSampleFunction.Arn LINEBotSampleFunctionIamRole: Description: "Implicit IAM Role created for LINE Bot Sample function" Value: !GetAtt LINEBotSampleFunctionRole.Arn
使用したバケットは、aws-sam-template-bucketとなってます。(これは、使いまわせません・・・)
$ aws s3 mb s3://aws-sam-template-bucket $ sam package --output-template-file packaged.yaml --s3-bucket aws-sam-template-bucket $ sam deploy --template-file packaged.yaml --stack-name line-bot-sample --capabilities CAPABILITY_IAM
デプロイが完了後、CloudFormationの出力から、LINEBotSampleApiの値をコピーして、LINE側のWebhook URLに設定します。
4 動作確認
動作している様子です。単純にオウム返ししているだけです。
5 最後に
今回は、Lambda+API GatewayによるLINEボットの超簡単なサンプルを試してみましちた。
LINEも色々な機能が満載です。このTypeScriptサンプルとTemplateを使いまわして、頑張って勉強してみたいと思います。